﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.NetworkInformation;

namespace com.utils.network
{
    /// <summary>
    /// Adapted from : http://stackoverflow.com/questions/520347/c-sharp-how-do-i-check-for-a-network-connection
    /// </summary>
    class NetworkConnectivity
    {
        /// <summary>
        /// Any network connection is available or not
        /// all loopbacks , virtual adapter and tunnels are filtered
        /// </summary>
        /// <returns> true if available</returns>
        public static bool isNetworkAvailable()
        {
            return isNetworkAvailable(0);
        }
        /// <summary>
        /// Network connection availability with speed Thresholds
        /// </summary>
        /// <param name="speedThreshold"></param>
        /// <returns></returns>
        public static bool isNetworkAvailable(long speedThreshold)
        {
            if (!NetworkInterface.GetIsNetworkAvailable())
            {
                return false;
            }
            foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
            {
                // discard if down , loopback or tunneled
                if ((ni.OperationalStatus != OperationalStatus.Up) ||
                    (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
                    (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
                    continue;

                // this allow to filter modems, serial, etc.
                //  use 10000000 as a minimum speed for most cases
                //  0 if limted connectivity is allowed
                if (ni.Speed < speedThreshold)
                    continue;

                // discard virtual cards (virtual box, virtual pc, etc.)
                if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) ||
                    (ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0))
                    continue;

                // discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
                if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
                    continue;

                return true;
            }
            return false;
        }
    }
}
